package org.example;

/**
 * 超市水果计价系统
 * 1. 顾客A购买苹果和草莓
 * 2. 顾客B购买苹果、草莓和芒果
 * 3. 顾客C购买水果，草莓打8折
 * 4. 顾客D购买水果，满100减10
 */
public class Main {
    public static void main(String[] args) {
        // 创建超市计价器
        SupermarketCalculator calculator = new SupermarketCalculator();
        
        System.out.println("=== 超市水果计价系统 ===\n");
        
        // 顾客A购买苹果和草莓
        customerA(calculator);
        
        // 顾客B购买苹果、草莓和芒果
        customerB(calculator);
        
        // 顾客C购买水果，草莓打8折
        customerC(calculator);
        
        // 顾客D购买水果，满100减10
        customerD(calculator);
    }
    /**
     * 顾客A购买苹果和草莓
     */
    private static void customerA(SupermarketCalculator calculator) {
        System.out.println("顾客A购买苹果和草莓");
        System.out.println("价格：苹果8元/斤，草莓13元/斤");
        
        // 苹果3斤，草莓2斤
        double total1 = calculator.calculateForCustomerA(3, 2);
        double expected1 = 3 * 8 + 2 * 13;
        System.out.printf("购买苹果3斤，草莓2斤：总价%.2f元（预期%.2f元）%s\n", 
                          total1, expected1, total1 == expected1 ? "✓" : "✗");
        
        // 苹果5斤，草莓0斤
        double total2 = calculator.calculateForCustomerA(5, 0);
        double expected2 = 5 * 8 + 0 * 13;
        System.out.printf("购买苹果5斤，草莓0斤：总价%.2f元（预期%.2f元）%s\n", 
                          total2, expected2, total2 == expected2 ? "✓" : "✗");
        
        System.out.println();
    }
    
    /**
     * 顾客B购买苹果、草莓和芒果
     */
    private static void customerB(SupermarketCalculator calculator) {
        System.out.println("顾客B购买苹果、草莓和芒果");
        System.out.println("价格：苹果8元/斤，草莓13元/斤，芒果20元/斤");
        
        // 苹果2斤，草莓1斤，芒果1斤
        double total1 = calculator.calculateForCustomerB(2, 1, 1);
        double expected1 = 2 * 8 + 1 * 13 + 1 * 20;
        System.out.printf("购买苹果2斤，草莓1斤，芒果1斤：总价%.2f元（预期%.2f元）%s\n", 
                          total1, expected1, total1 == expected1 ? "✓" : "✗");
        
        // 苹果4斤，草莓3斤，芒果2斤
        double total2 = calculator.calculateForCustomerB(4, 3, 2);
        double expected2 = 4 * 8 + 3 * 13 + 2 * 20;
        System.out.printf("购买苹果4斤，草莓3斤，芒果2斤：总价%.2f元（预期%.2f元）%s\n", 
                          total2, expected2, total2 == expected2 ? "✓" : "✗");
        
        System.out.println();
    }
    
    /**
     * 顾客C购买水果，草莓打8折
     */
    private static void customerC(SupermarketCalculator calculator) {
        System.out.println("顾客C购买水果，草莓打8折");
        System.out.println("价格：苹果8元/斤，草莓13元/斤*0.8=10.4元/斤，芒果20元/斤");
        // 苹果2斤，草莓1斤，芒果1斤
        double total1 = calculator.calculateForCustomerC(2, 1, 1);
        double expected1 = 2 * 8 + 1 * 13 * 0.8 + 1 * 20;
        System.out.printf("购买苹果2斤，草莓1斤，芒果1斤：总价%.2f元（预期%.2f元）%s\n", 
                          total1, expected1, Math.abs(total1 - expected1) < 0.01 ? "✓" : "✗");
        // 苹果1斤，草莓5斤，芒果0斤
        double total2 = calculator.calculateForCustomerC(1, 5, 0);
        double expected2 = 1 * 8 + 5 * 13 * 0.8 + 0 * 20;
        System.out.printf("购买苹果1斤，草莓5斤，芒果0斤：总价%.2f元（预期%.2f元）%s\n", 
                          total2, expected2, Math.abs(total2 - expected2) < 0.01 ? "✓" : "✗");
        
        System.out.println();
    }
    
    /**
     * 顾客D购买水果，满100减10
     */
    private static void customerD(SupermarketCalculator calculator) {
        System.out.println("顾客D购买水果，满100减10");
        System.out.println("价格：苹果8元/斤，草莓13元/斤*0.8=10.4元/斤，芒果20元/斤，满100减10");
        // 苹果5斤，草莓3斤，芒果2斤（总价超过100）
        double total1 = calculator.calculateForCustomerD(5, 3, 2);
        double beforeDiscount1 = 5 * 8 + 3 * 13 * 0.8 + 2 * 20;
        double expected1 = beforeDiscount1 >= 100 ? beforeDiscount1 - 10 : beforeDiscount1;
        System.out.printf("购买苹果5斤，草莓3斤，芒果2斤：总价%.2f元（预期%.2f元）%s\n", 
                          total1, expected1, Math.abs(total1 - expected1) < 0.01 ? "✓" : "✗");
        // 苹果2斤，草莓2斤，芒果1斤（总价不满100）
        double total2 = calculator.calculateForCustomerD(2, 2, 1);
        double beforeDiscount2 = 2 * 8 + 2 * 13 * 0.8 + 1 * 20;
        // 不满100，无优惠
        double expected2 = beforeDiscount2;
        System.out.printf("购买苹果2斤，草莓2斤，芒果1斤：总价%.2f元（预期%.2f元）%s\n", 
                          total2, expected2, Math.abs(total2 - expected2) < 0.01 ? "✓" : "✗");
        // 苹果0斤，草莓8斤，芒果1斤（总价刚好100）
        double total3 = calculator.calculateForCustomerD(0, 8, 1);
        double beforeDiscount3 = 0 * 8 + 8 * 13 * 0.8 + 1 * 20;
        double expected3 = beforeDiscount3 >= 100 ? beforeDiscount3 - 10 : beforeDiscount3;
        System.out.printf("购买苹果0斤，草莓8斤，芒果1斤：总价%.2f元（预期%.2f元）%s\n", 
                          total3, expected3, Math.abs(total3 - expected3) < 0.01 ? "✓" : "✗");
        System.out.println();
    }
}

/**
 * 水果枚举类，定义水果类型和基础价格
 */
enum Fruit {
    APPLE(8.0, "苹果"),
    STRAWBERRY(13.0, "草莓"),
    MANGO(20.0, "芒果");
    private final double basePrice;
    private final String name;
    Fruit(double basePrice, String name) {
        this.basePrice = basePrice;
        this.name = name;
    }
    public double getBasePrice() {
        return basePrice;
    }
    public String getName() {
        return name;
    }
}

/**
 * 超市计价器类
 */
class SupermarketCalculator {
    
    /**
     * 顾客A购买苹果和草莓的计价
     * @param appleWeight 苹果重量（斤）
     * @param strawberryWeight 草莓重量（斤）
     * @return 总价格
     */
    public double calculateForCustomerA(int appleWeight, int strawberryWeight) {
        validateWeight(appleWeight, strawberryWeight);
        double appleTotal = appleWeight * Fruit.APPLE.getBasePrice();
        double strawberryTotal = strawberryWeight * Fruit.STRAWBERRY.getBasePrice();
        return appleTotal + strawberryTotal;
    }
    
    /**
     * 顾客B购买苹果、草莓和芒果的计价
     * @param appleWeight 苹果重量（斤）
     * @param strawberryWeight 草莓重量（斤）
     * @param mangoWeight 芒果重量（斤）
     * @return 总价格
     */
    public double calculateForCustomerB(int appleWeight, int strawberryWeight, int mangoWeight) {
        validateWeight(appleWeight, strawberryWeight, mangoWeight);
        double appleTotal = appleWeight * Fruit.APPLE.getBasePrice();
        double strawberryTotal = strawberryWeight * Fruit.STRAWBERRY.getBasePrice();
        double mangoTotal = mangoWeight * Fruit.MANGO.getBasePrice();
        return appleTotal + strawberryTotal + mangoTotal;
    }
    
    /**
     * 顾客C购买水果，草莓打8折
     * @param appleWeight 苹果重量（斤）
     * @param strawberryWeight 草莓重量（斤）
     * @param mangoWeight 芒果重量（斤）
     * @return 总价格
     */
    public double calculateForCustomerC(int appleWeight, int strawberryWeight, int mangoWeight) {
        validateWeight(appleWeight, strawberryWeight, mangoWeight);
        final double STRAWBERRY_DISCOUNT = 0.8; // 草莓打8折
        double appleTotal = appleWeight * Fruit.APPLE.getBasePrice();
        double strawberryTotal = strawberryWeight * Fruit.STRAWBERRY.getBasePrice() * STRAWBERRY_DISCOUNT;
        double mangoTotal = mangoWeight * Fruit.MANGO.getBasePrice();
        return appleTotal + strawberryTotal + mangoTotal;
    }
    
    /**
     * 顾客D购买水果，草莓打8折，满100减10
     * @param appleWeight 苹果重量（斤）
     * @param strawberryWeight 草莓重量（斤）
     * @param mangoWeight 芒果重量（斤）
     * @return 总价格
     */
    public double calculateForCustomerD(int appleWeight, int strawberryWeight, int mangoWeight) {
        validateWeight(appleWeight, strawberryWeight, mangoWeight);
        // 草莓打8折
        final double STRAWBERRY_DISCOUNT = 0.8;
        // 满减门槛
        final double FULL_REDUCTION_THRESHOLD = 100.0;
        // 满减金额
        final double FULL_REDUCTION_AMOUNT = 10.0;
        // 先计算打折后的价格
        double appleTotal = appleWeight * Fruit.APPLE.getBasePrice();
        double strawberryTotal = strawberryWeight * Fruit.STRAWBERRY.getBasePrice() * STRAWBERRY_DISCOUNT;
        double mangoTotal = mangoWeight * Fruit.MANGO.getBasePrice();
        double subtotal = appleTotal + strawberryTotal + mangoTotal;
        // 应用满减优惠
        if (subtotal >= FULL_REDUCTION_THRESHOLD) {
            subtotal -= FULL_REDUCTION_AMOUNT;
        }
        return subtotal;
    }
    
    /**
     * 验证重量参数是否有效（非负整数）
     * @param weights 重量参数
     * @throws IllegalArgumentException 如果重量为负数
     */
    private void validateWeight(int... weights) {
        for (int weight : weights) {
            if (weight < 0) {
                throw new IllegalArgumentException("水果重量不能为负数：" + weight);
            }
        }
    }
}